package com.then.basic.socket;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 线程辅助类
 */
public class ThreadUtil {

    static final String TAG = "ThreadUtil";

    // 按需创建新线程，如果有可以复用的线程，就复用
    // 适用于不能排队，必须立马开启线程执行的场景
    static volatile ExecutorService sCachePoll;

    // 线程最大数量受限制，如果可执行runnable的线程不足，那么排队
    // 适用于可以适当排队的场景
    static volatile ExecutorService sQueuePoll;

    // 用于使代码在主线程执行
    static volatile Handler sMainHandler;

    static final int MAX_THREAD_SIZE = Runtime.getRuntime().availableProcessors() + 1;

    private static void initCachedPoll() {
        if (sCachePoll == null) {
            synchronized (ThreadUtil.class) {
                if (sCachePoll == null) {
                    Log.d(TAG, "initCachePoll");
                    sCachePoll = Executors.newCachedThreadPool(new NamedThreadFactory("Cached"));
                }
            }
        }
    }

    private static void initQueuedPoll() {
        if (sQueuePoll == null) {
            synchronized (ThreadUtil.class) {
                Log.d(TAG, "initQueuedPoll max:" + MAX_THREAD_SIZE);
                sQueuePoll = Executors.newFixedThreadPool(MAX_THREAD_SIZE, new NamedThreadFactory("Queued"));
            }
        }
    }

    public static ExecutorService getCachedExecutor() {
        initCachedPoll();
        return sCachePoll;
    }

    public static ExecutorService getQueuedExecutor() {
        initQueuedPoll();
        return sQueuePoll;
    }

    private static void initMainHandler() {
        if (sMainHandler == null) {
            synchronized (ThreadUtil.class) {
                if (sMainHandler == null) {
                    sMainHandler = new Handler(Looper.getMainLooper());
                }
            }
        }
    }

    /**
     * 立即异步执行Runnable
     * @param r
     */
    public static void async(Runnable r) {
        initCachedPoll();
        sCachePoll.execute(r);
    }

    /**
     * 异步执行Runnable，如果异步执行队列已满，那么排队执行
     * @param r
     */
    public static void asyncQueued(Runnable r) {
        initQueuedPoll();
        sQueuePoll.execute(r);
    }

    /**
     * 将Runnable放到ui线程排队执行
     * @param r
     */
    public static void ui(Runnable r) {
        initMainHandler();
        sMainHandler.post(r);
    }

    public static void ui(Runnable r, long delayed) {
        initMainHandler();
        sMainHandler.postDelayed(r, delayed);
    }


    /**
     * The default thread factory
     */
    public static class NamedThreadFactory implements ThreadFactory {

        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        public NamedThreadFactory(String factoryName) {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                    Thread.currentThread().getThreadGroup();
            namePrefix = factoryName + "-thread-";
        }

        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                    namePrefix + threadNumber.getAndIncrement(),
                    0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }
}
